package io.polly.secure;

import cn.hutool.core.thread.ThreadFactoryBuilder;
import lombok.extern.slf4j.Slf4j;
import com.google.common.collect.Lists;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

/**
 * @author ldz
 * @version V1.0
 * @title: CompletableFutureMain
 * @description: TODO(用一句话描述该文件做什么)
 * @date: 2022/4/1 20:34
 */
@Slf4j
public class CompletableFutureMain {

    //分批进行阈值
    public static final int threshold = 5;
    //并发数
    public static final int parallelNum = 3;

    public static void main(String[] args) {
        List<String> userList = Arrays.asList("1","2","3","a");
        List<List<String>> partUserList = Lists.partition(userList,threshold);
        log.info("partUserList.size():{}"+partUserList.size());

        List<List<List<String>>> subPartUserList = new ArrayList<>(parallelNum);
        for(int j=0;j<parallelNum;j++)
        subPartUserList.add(new ArrayList<>());

        log.info("subPartUserList.size():{}"+subPartUserList.size());

        for (int i = 0; i < partUserList.size(); i++) {
            subPartUserList.get(i % parallelNum).add(partUserList.get(i));
        }

        CompletableFuture<?>[] allCompletableFutures = new CompletableFuture<?>[parallelNum];
        ThreadPoolExecutor threadPoolExecutor = createExecutor(parallelNum,parallelNum,"threadName--");

        for (int i = 0; i < parallelNum; i++) {
            List<List<String>> parallelUserList =  subPartUserList.get(i);
            allCompletableFutures[i] = CompletableFuture.runAsync(() -> {
                log.info("threadName:{}",Thread.currentThread().getName());
                parallelUserList.stream().forEach(System.out::println);
            },threadPoolExecutor);
        }

        CompletableFuture.allOf(allCompletableFutures).join();
        threadPoolExecutor.shutdown();
        log.info("end of parallel process");

    }

    private static ThreadPoolExecutor  createExecutor(int corePoolSize, int maxPoolSize, String threadNamePrefix) {
        ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNamePrefix(threadNamePrefix).build();
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maxPoolSize,
                30L, TimeUnit.SECONDS,
                new LinkedBlockingQueue(), namedThreadFactory);
        return threadPoolExecutor;
    }

}
